package com.semlab.client.fwk.ap;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.logging.Logger;

import com.google.gwt.activity.shared.ActivityMapper;
import com.google.gwt.user.client.ui.AcceptsOneWidget;

public class ApplicationMapping implements ContainerRegistry {

	private static final Logger log = Logger.getLogger(ApplicationMapping.class.getName());

	private ArrayList<ContainerMapping> containers = new ArrayList<ContainerMapping>();

	private HashSet<Place> placesForUpdate = new HashSet<Place>();

	public boolean hasContainer(String theContainerId) {
		if (containers != null) {
			for (ContainerMapping container : containers) {
				if (container.getId().equals(theContainerId)) {
					return true;
				}
			}
		}
		return false;
	}

	public void registerContainer(String theContainerId, AcceptsOneWidget display) {
		ContainerMapping container = getContainer(theContainerId);
		if(container != null){
//			log.fine(":: container exists, changing display widget.. ");
			container.setWidget(display);
		}else{
			containers.add(new ContainerMapping(theContainerId, display));
		}
	}

	public ArrayList<ContainerMapping> getContainers() {
		return containers;
	}

	@Override
	public String toString() {
		return "ApplicationMapping [containers=" + containers + "]";
	}

	@Override
	public void deregisterContainer(String id) {
		for (ContainerMapping container : containers) {
			if (container.getId().equals(id)) {
				container.removeManager();
			}
		}
	}

	public ContainerMapping getContainer(String id) {
		for (ContainerMapping container : containers) {
			if (container.getId().equals(id)) {
				return container;
			}
		}
//		log.fine(":: creating container");
		ContainerMapping container = new ContainerMapping(id);
		containers.add(container);
		return container ;

	}

	public void registerMapping(String containerId, MappingsEntry newMappingEntry) {
		getContainer(containerId).addMappingEntry(newMappingEntry);
	}

	public ActivityMapper getActivityMapperForPlace(String containerId, Place parPlace) {
		MappingsEntry mappingEntry = getContainer(containerId).getMappingsFor(parPlace);
		if (mappingEntry != null) {
			return mappingEntry.getActivityMapper();
		}
		return null;
	}

	public void scheduleMappingForUpdate(MappingsEntry newMappingEntry) {
//		log.fine(":: scheduling mapping for update. place= "+newMappingEntry.getParentPlace());
		placesForUpdate.add(newMappingEntry.getParentPlace());
	}

	public void updateMappings(MappingsEntry newEntry){
		Place place = newEntry.getPlace();
		if(placesForUpdate.contains(place)){
//			log.fine(":: place should update mappings - "+place);
			ArrayList<MappingsEntry> mappings = getContainer(place.getContainerId()).getPlaceMappings();
			for (MappingsEntry entry : mappings) {
				if(entry.getParentPlace() != null && entry.getParentPlace().equals(place)){
//					log.fine(":: updating mapping="+newEntry.getPlace()+" with ="+newEntry.getActivityMapper());
					entry.setActivityMapper(newEntry.getActivityMapper());
				}
			}
		}
	}
	
	public void clearMappingsForUpdate(){
		placesForUpdate.clear();
	}

}
